package Algorthim;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import javax.swing.JFrame;

import phylogenetictree.PhylogeneticTree;

import searchTree.searchTreeNode;

public class SingleThreaded extends Algorithim {

	public static void main(String[] data)
	{
		Algorithim myprogram = new SingleThreaded();
		PhylogeneticTree treeOne = null;
		PhylogeneticTree treeTwo = null;
		
		try {
			treeOne = new PhylogeneticTree("trees/wrongCuts");
			treeTwo = new PhylogeneticTree("trees/wrongCutsMut");
		} catch (IOException e) {
			e.printStackTrace();
		}

		JFrame dialog = new JFrame("tree one");
		dialog.setContentPane(GUI.TreeDisplayer.treeVeiwer(treeOne));
		dialog.setVisible(true);
		
		JFrame dialogtwo = new JFrame("tree two");
			dialogtwo.setContentPane(GUI.TreeDisplayer.treeVeiwer(treeTwo));
			dialogtwo.setVisible(true);
			
			ArrayList<searchTreeNode> results = myprogram.solve(treeOne,treeTwo,2,5);
			Collections.sort(results,new Comparator<searchTreeNode>() {

				@Override
				public int compare(searchTreeNode o1, searchTreeNode o2) {
					int one = o1.getNumberOfCuts();
					int two = o2.getNumberOfCuts();
					if( one > two)
					{
						return 1;
					}
					else if (two > one)
					{
						return -1;
					}
					else
					{
						return 0;
					}
				}
			});
			
			for(searchTreeNode result:results)
			{
			
				System.out.println("Final Soultion in " + result.getNumberOfCuts() + " cuts");
				System.out.println(result.getTree().toCommaSeperatedFile()); 
				System.out.println(); 
			}
			
			searchTreeNode result = results.get(0);
			JFrame dialogThree = new JFrame("soultion");
			dialogThree.setContentPane(GUI.TreeDisplayer.treeVeiwer(result.getTree()));
			dialogThree.setVisible(true);
	}
	
	@Override
	protected void handlePhaseOneReturn(searchTreeNode node, Integer firstleaf,
			Integer JunctionOne, Integer secoundleaf,
			Integer JunctionTwo, Integer thirdleaf, Integer forthleaf) 
	{
//		System.out.println(node.getTree().indexMap.get(JunctionOne) + ", " + node.getTree().indexMap.get(JunctionTwo) + " Junctions for " + node.getTree().indexMap.get(firstleaf) + ","+node.getTree().indexMap.get(secoundleaf) + "|" + node.getTree().indexMap.get(thirdleaf) + "," + node.getTree().indexMap.get(forthleaf));
		searchTreeNode optionOne = cloner.deepClone(node);
		optionOne.cutBranch(globaldata.getPathMap(),firstleaf, JunctionOne);
		phaseOne(optionOne);
		
		searchTreeNode optionTwo = cloner.deepClone(node);
		optionTwo.cutBranch(globaldata.getPathMap(),secoundleaf, JunctionOne);
		phaseOne(optionTwo);
		
		searchTreeNode optionThree = cloner.deepClone(node);
		optionThree.cutBranch(globaldata.getPathMap(),thirdleaf, JunctionTwo);
		phaseOne(optionThree);
		
		searchTreeNode optionFour = cloner.deepClone(node);
		optionFour.cutBranch(globaldata.getPathMap(),forthleaf, JunctionTwo);
		phaseOne(optionFour);
		return;

	}

	@Override
	protected void handlePhaseOneComplete(searchTreeNode node) {		
		this.createTranslation(node);
		this.phaseTwo(node);
	}

	@Override
	protected void handlePhaseTwoReturn(searchTreeNode node, Integer[] edgeOne,Integer[] edgeTwo)
	{
		searchTreeNode nodeOne = cloner.deepClone(node);
		searchTreeNode nodeTwo = node;

		nodeOne.getTree().removeEdge(edgeOne[0], edgeOne[1]); 
		nodeTwo.getTree().removeEdge(edgeTwo[0], edgeTwo[1]);

		phaseTwo(nodeOne);
		phaseTwo(nodeTwo);
	}

}
